/**
*File name: cellNetwork.h
*This file declares the structures and functions of the system.
*\Author: Tran Van Hoang
*\date:01-02-2015
*\Version: $ Reversion:1.0 $
*Contact: tvhoang75@gmail.com
*/

#ifndef CELLNETWORK_H
#define CELLNETWORK_H

#include <stdio.h>
#include <curand_kernel.h>

#define MAX_NUM_CRICKET 150

//Network define
#define NODE_NUMBER 1220
#define MAX_FANOUT 8
#define DYNAMIC_CHAN 5
#define MAX_MOBILE 3

/*********************************FEDERATION**************************************************/
#define NODE_NUMBER_RIVER 893
#define NODE_NUMBER_SENSOR_NET 601 
#define NODE_NUMBER_FOREST 3365
#define NODE_NUMBER_FRONTIER 354 

/*********************************RIVER FEDERATE**************************************************/
#define MAX_POLLUTION_DENSITY 10

/*********************************NETWORK FEDERATE**************************************************/
//Some definitions for NetworkFederate
#define SENSOR_NET_NORMAL 1
#define SENSOR_NET_URGENT 2
/*********************************FOREST FEDERATE**************************************************/
//Some definitions for ForestFederate
#define NORMAL 1
#define FIRED 2
#define ASH 3
#define EMPTY 4


typedef struct{
	//int treeDensity;//possibility affect to the density of the ash
	int treeState;///NORMAL | FIRED | ASH | EMPTY
}TreeState;
/*******************************CRICKETS FEDERATE***************************************************/
//This structure allows to create message for storing information (the number of crickets that the node recevied from the neighbors) exchaging between one node and its neighbors every step.
typedef struct{
	int nbCrickets;//Number of crickets that the node receive from its neighbors.
}Message;

typedef struct{
	int limit;
	Message message[MAX_FANOUT];
}MessageList;
///This strcuture defines relative position of neighbor of each node (cell)
///For example, the value of x, and y as the following with the distance = 1: 
///North: (0,-1); West(-1,0); East(1,0); South(0,1) 
typedef struct 
{
	int x;
	int y;
}Direction;
/**
*This structure is automatically  created  from NetGen tool.
*
*/
typedef struct s_mapped
{
	int node;
	int canal;
	Direction direction;        
}mapped;

typedef struct s_canaux
{
	int nbOut;
	int nbIn;
	int nbDyn;
	mapped write[MAX_FANOUT];
	mapped read[MAX_FANOUT];
	mapped writeDyn[DYNAMIC_CHAN];
	mapped readDyn[DYNAMIC_CHAN];
}canaux;

typedef struct
{	
	int x;
	int y;
	int range;	
}node_param;

/**
*This structure is automatically  created  from NetGen tool.
*
*/

struct ImageExtent {
      int width; 
      int height;
};

struct CellPosition { 
   int x,y;
};

struct RGBPixel {
    unsigned char red, green, blue;
};

typedef struct RGBPixel Depth24ByteArray[100]; 

typedef struct CellImage {  
		       struct ImageExtent  extent;
                       Depth24ByteArray pixelArray;    
} CellImage; 

typedef struct  CellArray
{ 
    CellPosition position;
    CellImage image; 
} CellArray;

/**
* This structure defines attributes of an object typed Shark.
*/

typedef struct{
	int id;//id of Shark	
}Shark;

/**
*
*/

typedef union{
	int file;
	Shark shark;
}PacketType;

typedef struct{
	int limit;
	int newFound[NODE_NUMBER - 1];
}FileOfId;

typedef struct{
	int destId, srcId;
	PacketType packetType;
}Packet;

typedef struct{
	int Id, Distance, IndexLink;	
}KnownId;

typedef struct{
	int limit;
	KnownId knownTab[NODE_NUMBER - 1];
}TabNeighbours;

typedef struct{
	FileOfId currentFiles[MAX_FANOUT];
	bool markers[MAX_FANOUT];
	int maxLoc;
	int maxGlobal;
}Buffer;

/*
typedef struct{
	int food;
	float density;//Pollution density
	int nbCrickets;//Number of crickets
	MessageList messageList;//Number of messages received from its neighbor 
}NodeState;
*/

typedef struct{
	float density;//Pollution density
	//int nbCrickets;//Number of crickets
	//MessageList messageList;//Number of messages received from its neighbor 
}NodeState;

typedef struct{
	CellPosition cellPosition;
	NodeState nodeState;	
	TreeState tree;
}Node;

typedef struct{
	CellPosition position;
	int sensorState; //SENSOR_NET_NORMAL | SENSOR_NET_URGENT
}SensorNode;

//#include "functions.cu"
//#include "functions_par.cu"

//---------------------------------------------------------------------
/**Random number generator
****/
/***************** FOREST FEDERATE *************************************/

extern void initTreeState(TreeState *node_state, int node_number, int num_fired_node);

extern __device__ TreeState computeStateForest(TreeState *nowState_d, int nodeIndex, canaux *channels_d, curandState* devState_d);

extern __global__ void stepStateForest(TreeState *nowState_d, TreeState *nextState_d, canaux *channels_d, int node_number, curandState *devStates_d);

extern __global__ void setup_kernel(curandState *state, unsigned long seed);

/*********Crickets*******************************/

//extern __global__ void initStateCricket(NodeState *node_state_d, curandState *devStates_d, int node_number);

extern void initStateCricket(NodeState *node_state, int node_number);
//extern void initCricket(NodeState *state, int number);

extern __device__ NodeState computeStateCricket(NodeState *nowState_d, int nodeIndex, canaux *channels_d);

extern __global__ void stepStateCricket(NodeState *nowState_d, NodeState *nextState_d, canaux *channels_d, int node_number, curandState *devStates_d);

extern __global__ void updateNodeState(NodeState *nowState_d, NodeState *nextState_d, int node_number);

/*********Pollution Diffusion****************/
extern void initState_v1(NodeState *state, int node_number, int num_polluted_node);

extern void initState(NodeState *state, int number);

extern void initStateCricket(NodeState *state, int number);

extern __global__ void stepState(NodeState *nowState_d, NodeState *nextState_d, canaux *channels_d, int node_number, curandState *devStates_d);

extern void stepState_h(NodeState *nowState_d, NodeState *nextState_d, canaux *channels_d, int node_number);

//Generating network function declaration
extern int FindIndexPosition(CellPosition cell, CellArray *cells, int node_number);

extern CellPosition FindMinPosition(CellArray *cells, int node_number);

extern CellPosition FindMaxPosition(CellArray *cells, int node_number);

extern CellPosition  FindMaxPosition(CellArray *cells, int node_number);

extern void GenerateNetwork(char *fileName, char *pattern, CellArray *cells, int node_number);
//Cellular Automata functions
extern void  initNodeState(int *now_h, int *next_h, int node_number);

extern __device__ int doSum(int index);

extern __global__ void changeState(int now[], int next[], canaux channels[], int node_number);

extern __device__ int computeLife(int state, int sum);

int doSum_h(int node, canaux channels[], int s_h[]);

//Routing functions

extern void WriteDotFile(char *fileName, FileOfId route);

extern void InitPacket(PacketType type, Packet *paq, int pac_number, int node_number);

extern void RoutingPacket(Packet pac, TabNeighbours *tabs, canaux *channels, FileOfId &route);

extern int FindMaxDistance_h(TabNeighbours tab);

extern void WriteMaxRoutes(char *fileName, TabNeighbours tab, canaux *channels);

extern void WriteRouteTable(char *fileName, TabNeighbours tab, canaux *channels);

extern void WriteNetwork(char *fileName, canaux *channels, int node_number);

extern bool FoundIdInFile_h(int id, FileOfId file);

extern __device__ int FindMaxDistance(TabNeighbours tab);

extern __device__ bool FoundIdInFile(int id, FileOfId file);

extern __device__ bool IsLinked(int src, int dest, canaux *channels);

extern bool IsLinked_h(int src, int dest, canaux *channels);

extern __device__ void ResetFile(FileOfId &file);

extern void ResetFile_h(FileOfId &file);

extern __device__ void ResetTab(TabNeighbours &tab);

extern __device__ void AddIdInFile(int id, FileOfId &file);

extern void AddIdInFile_h(int id, FileOfId &file);

extern __device__ void AddIdInTab(int id, int distance, int indexLink, TabNeighbours &tab);

extern __device__ bool FoundIdInTab(int id, TabNeighbours tab);

extern __global__ void Init(TabNeighbours *tabs, Buffer *buffer, canaux *channels_d, int node_number);

extern __global__ void Distances(TabNeighbours *tabs, Buffer *buffer, canaux *channels_d, int node_number, int turn);

extern __global__ void GettingMaxLoc(TabNeighbours *tabs, Buffer *buffer, int node_number);

extern __global__ void ComputeMaxGlobal(Buffer *buffer, canaux *channels_d, int node_number);

extern void DumpFile(FileOfId file);

extern void DumpTab(TabNeighbours *tabs, int node_number);

extern void DumpMaxLoc(Buffer *buffer, int node_number);

extern void simulatingRiver(curandState* devState_d);

extern void simulatingRiver_h();

extern void simulatingRiverGUI_h();;

extern void simulatingRiverGUI(curandState* devState_d);
#endif
